﻿using System;
using System.Collections.Generic;
using System.Data.Objects;
using System.IO;
using System.Linq;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;

namespace IkSan.ExtJs4EF4
{
    public static class ObjectSetExtension
    {
        private static readonly JsonSerializer JsonSerializer = new JsonSerializer
        {
            DefaultValueHandling = DefaultValueHandling.Ignore
        };

        static ObjectSetExtension()
        {
            JsonSerializer.Converters.Add(new IsoDateTimeConverter());            
        }
        
        public static ObjectQuery<T1> AddFilters<T1>(this ObjectQuery<T1> objectQuery, IEnumerable<Filter> filters) where T1 : class
        {
            if(filters==null || filters.Count()==0)
            {
                return objectQuery;
            }

            var filtertring = string.Join(" AND ", filters.Select(f => string.Format("it.{0} = @{0}", f.property)));
            var objectParameters = new List<ObjectParameter>();
            var type = typeof(T1);

            foreach (var filter in filters)
            {
                var property = type.GetProperty(filter.property);
                if (property == null)
                {
                    throw new ApplicationException(string.Format("Could not find property {0} to filter on.", filter.property));
                }
                var value = property.PropertyType == typeof (string)
                                   ? filter.value
                                   : JsonSerializer.Deserialize(new StringReader(filter.value), property.PropertyType);
                objectParameters.Add(new ObjectParameter(filter.property, value));
            }

            return objectQuery.Where(filtertring, objectParameters.ToArray());
        }

        public static ObjectQuery<T1> AddSorters<T1>(this ObjectQuery<T1> objectQuery, IEnumerable<Sort> sorters) where T1 : class
        {
            if(sorters==null || sorters.Count()==0)
            {
                return objectQuery;
            }
            return sorters.Aggregate(objectQuery,
                                     (current, s) =>
                                     current.OrderBy(string.Format("it.{0} {1}", s.property, s.direction)));
        }

    
    }
}